链接方式的区别
关于链接方式的区别
动态库的调用链接方式
动态库调用方式可分为两种:
- 显式调用
- 隐式调用
两种调用方式
显式调用
在程序中直接通过动态库装载的方式,对程序中定义的 [函数指针]进行加载和赋值。
下面是用例:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849//定义函数指针 以及变量void *functionLib; /* Handle to shared lib file */char *dlError; /* Pointer to error string *///magint (*NDK_MagOpen)(void);int (*NDK_MagClose)(void);int (*NDK_MagSwiped)(uchar * psSwiped);int (*NDK_MagReadNormal)(char *pszTk1, char *pszTk2, char *pszTk3, int *pnErrorCode);// ... 省略N行 ...// onload.c// 定义了一个加载宏#define DLSYM(lib, foo) { \dlError = (char *)dlerror(); \foo = dlsym( lib , #foo); \if( dlError || NULL == foo ){ \foo = NULL; \nRet -= 1; \LOGI("dlsym "#foo" fail:%s,Addr:%x,nRet:%d.",dlError, (int)foo, nRet); \} \else{ \LOGI("dlsym "#foo" succ. Addr:%x.", (int)foo); \} \}; \//------- 通过显示加载方式加载库文件 --------------------int nRet = 0; /* return codes */// libnl_ndk.so// libnlposapi.sofunctionLib = dlopen("/system/lib/libabcd.so",RTLD_LAZY);dlError = (char *)dlerror();LOGI("dlopen libnlposapi.so error:%s", dlError);if( functionLib == NULL ){return (-1000);}//magDLSYM(functionLib, NDK_MagOpen);DLSYM(functionLib, NDK_MagClose);DLSYM(functionLib, NDK_MagSwiped);DLSYM(functionLib, NDK_MagReadNormal);// ... 省略N行 ...这时候 在mk文件中可以不需要链接这个库(libabcd.so)就可以调用这个库里面的函数。
像这样:
int ret= NDK_MagOpen();
这时NDK头文件中也将函数声明定义为函数指针的方式:
int (*NDK_MagOpen)();
隐式调用
即通过在mk文件中显示指定需要调用链接的函数库的名称,然后在程序运行的过程中由os系统中的装载器以及链接器来完成函数的装载和链接过程。
如果一个函数定义在libabcd.so中时,我们需要调用它,就要在Android.mk文件中显示指定调用链接函数库名称:
LOCAL_LDLIBS += labcd
然后在NDK头文件中声明为函数调用方式(注意区别前面的函数指针的什么方式):
int NDK_MagOpen();
然后调用方式同函数指针的方式:
int ret= NDK_MagOpen();